テクニカル Q&A

HW 49 - 特定の ROM-in-RAM 型 Macintosh を検出するには(1999年10月5日更新)


Q: ROM-in-RAM 型(New World)Macintosh はどれも Gestalt のマシン ID として 406(10進)を返しますが、Macintosh を特定するにはどうすればよいでしょうか?

A: この場合は Name Registry に問い合わせて情報を取得する必要があります。

重要: ある機能が存在するかどうかを推測する際に、マシン ID をチェックしてはいけません。特定の機能の有無を調べるには、Name Registry か Gestalt を使用してください。特定の機能が存在するかどうかを調べる際にマシン ID をチェックする以外に方法がないという場合は、今後の修正のために、バグレポートをこちらまで送付してください。


Macintosh の全世界共通名は、compatible プロパティから取得することができます。このプロパティの値は C 形式の文字列で、名前はプロパティ値の最初のエントリで表されます。compatible プロパティは“Devices:device-tree”パスにあります。この値は 99 年の Power Macintosh G3 では“PowerMac1,1”、iMac では“iMac,1”となっています。

注意: この文字列はユーザに対して表示するものではないため、ローカライズされていません。この文字列はユーザに対して表示しないでください。

これらの文字列はローカライズされていないため、簡単にテストすることができます。ただし、ユーザからは見えないようにしてください。

注意: 現時点では、iMac は全機種で“iMac,1”という同じ compatible プロパティ値を持っています。


Rage II を搭載した初代 iMac と Rage Pro を搭載した第2世代 iMac を見分けるには、“Devices:device-tree:pci:ATY,RageIIC_C”または“Devices:device-tree:pci:ATY,RagePro_C”の Name Registry ノードをそれぞれ探してください。また、“ATY,RageIIC_C”か“ATY,RagePro_C”の各 name プロパティを持つノードを探しても、同じ結果が得られます。

Rage Pro を搭載した 233 Mhz iMac と同じ Rage Pro を搭載した 266 iMac を見分けるには、CPU ノードの clock-frequency プロパティをチェックする必要があります。この場合は、device_type プロパティ値が「cpu¥0」となっているノードを探すのが最善です(ヌルターミネータもプロパティ値の一部に含まれるため、C 文字列のヌルターミネータを渡す必要があります。)この値を持ったノードが見つかれば、同じノード内で clock-frequency プロパティの値を知ることができます。clock-frequency プロパティを直接探すことはできません。ネームレジストリ内にはこのプロパティに関するエントリが数多くあり、その clock-frequency の値を見つけたとしても、それが CPU ノードから得られた値ではない可能性もあるからです。

重要: これまでの説明を見れば、特定の Macintosh を指定するという方法は推奨していないということがわかっていただけたと思います。コンピュータの機種だけに基づいて特定の機能の存在を仮定するのではなく、FireWire や USB など、必要となる特定の機能そのものを(Gestalt などの手段を用いて)探したほうがよいでしょう。

必要な機能がつねに特定の機種に備わっていると決めつけるよりは、必要な機能だけをチェックするようにしましょう。特定の機能をチェックする方法がないという理由でマシン ID を利用しているという場合は、バグレポートをこちらまで送付していただければ、選択子を追加することができます。


/* GetMacName は、model プロパティ文字列を
 * C 形式 (ヌルターミネートされた文字列) で返す。
 * Input  macName - バッファへのポインタ。呼び出しが成功すると、
 * model name プロパティ名はここに返される。
 *
 * Output function result - noErr は、機種名の読み出しに成功した
 * ことを示す。
 *        macName - noErr の場合、機種名のプロパティが格納される。
 *
 * 注意
 * 呼び出し元ルーチンは、macName の廃棄も行うこと。
 * その場合はDisposePtr を使用する。
 */
OSStatus GetMacName (StringPtr * macName) {
    OSStatus                err             = noErr;
    RegEntryID              compatibleEntry;
    RegPropertyValueSize    length;
    RegCStrEntryNamePtr     compatibleValue;
         
    if (macName != nil) {
        *macName = 0;
         
        err = RegistryEntryIDInit (&compatibleEntry);
         
        if (err == noErr) {
            err = RegistryCStrEntryLookup (nil, "Devices:device-tree", &compatibleEntry);
        }
         
        if (err == noErr) {
            err = RegistryPropertyGetSize (&compatibleEntry, "compatible", &length);
        }
         
        if (err == noErr) {
            compatibleValue = (RegCStrEntryNamePtr)NewPtr (length);
            err = MemError ();
        }
         
        if (err == noErr) {
            err = RegistryPropertyGet (&compatibleEntry, "compatible", compatibleValue, &length);
        }
         
        if (err == noErr) {
            SetPtrSize (compatibleValue, strlen (compatibleValue) + 1);
            /* SetPtrSize shouldn't fail because we are shrinking the pointer, but make sure. */
            err = MemError ();
        }
         
        if (err == noErr) {
            *macName = c2pstr (compatibleValue);
        }
         
        (void)RegistryEntryIDDispose (&compatibleEntry);
    }
         
    return err;
}
         
/* GetMacSpeed は CPU ノードの clock-frequency プロパティを返す
 *
 * Output function result - noErr は CPU ノードの clock-frequency
 * プロパティが正常に読み出せたことを示す。
 *        cpuFreq   - noErr の場合、clock-frequency プロパティが格納される。
 *                    clock-frequency が読み出せなかった場合は 0 にセットされる。
*/
OSStatus GetMacSpeed (UInt32 * cpuFreq) {
    OSStatus                err             = noErr;
    RegEntryID              cpuEntry;
    RegEntryIter            cookie          = nil;
    RegEntryIterationOp     iterOp          = kRegIterDescendants;
    unsigned long           cpuSpeedSize    = sizeof (unsigned long);
    char *                  cpuValue        = "cpu";
    Boolean                 done;
         
    if (cpuFreq != nil) {
        *cpuFreq = 0;
    } else {
        cpuSpeedSize = 0;
    }
         
    if (err == noErr) {
        err = RegistryEntryIDInit (&cpuEntry);
    }
         
    if (err == noErr) {
        err = RegistryEntryIterateCreate (&cookie);
    }
         
    if (err == noErr) {
        err = RegistryEntrySearch (&cookie, iterOp, &cpuEntry, &done, "device_type", 
          cpuValue, strlen (cpuValue) + 1);
         
        if (done != true && err == noErr) {
            (void)RegistryPropertyGet (&cpuEntry, "clock-frequency", cpuFreq, &cpuSpeedSize);
        }
    }
         
    (void)RegistryEntryIDDispose (&cpuEntry);
    (void)RegistryEntryIterateDispose (&cookie);
         
    return err;
}

上のサンプルコードでは、ネームレジストリに機種名とクロック周波数それぞれの値を問い合わせるための方法を示しています。


-- Mark Cookson
Worldwide Developer Technical Support

テクニカル Q&A | 目次

To contact us, please use the Contact Us page.